<?php
/**
 * Created by PhpStorm.
 * User: renyi
 * Date: 2019-01-21
 * Time: 11:08
 */

namespace App\Base;

class BaseRepository
{
    protected $model = '';

    /**
     * 获得数组中该变量
     *
     * @param        $key
     * @param        $array
     * @param string $default
     *
     * @return mixed
     */
    public function value($key, $array, $default = '')
    {
        if (array_key_exists($key, $array))
        {
            return $array[$key];
        }

        return $default;
    }

    /**
     * 判断数组中是否有该变量
     *
     * @param $key
     * @param $array
     *
     * @return bool
     */
    public function has_value($key, $array)
    {
        if (array_key_exists($key, $array))
        {
            return true;
        }

        return false;
    }

    /**
     * 获得一个符合条件的数据对象
     *
     * @param $bundle
     *
     * @return mixed
     */
    public function first($bundle)
    {
        // extract
        $columns    = $this->value('columns', $bundle, []);
        $conditions = $this->value('conditions', $bundle, []);
        if (empty($columns) && empty($conditions) && count($bundle) > 0)
        {
            $conditions = $bundle;
        }

        $db = ($this->model)::query();

        foreach ($conditions as $name => $condition)
        {
            $db->where($name, $condition);
        }

        // LogHelper::info('BaseRepository first sql', $db->toSql());

        if (empty($columns))
        {
            return $db->first();
        }
        else
        {
            return $db->first($columns);
        }
    }

    /**
     * 获得所有符合条件的数据对象
     *
     * @param $bundle
     *
     * @return mixed
     */
    public function get($bundle)
    {
        // extract
        $columns    = $this->value('columns', $bundle, []);
        $conditions = $this->value('conditions', $bundle, []);
        if (empty($columns) && empty($conditions) && count($bundle) > 0)
        {
            $conditions = $bundle;
        }

        $db = ($this->model)::query();

        foreach ($conditions as $name => $condition)
        {
            $db->where($name, $condition);
        }

        // LogHelper::info('BaseRepository get sql', $db->toSql());

        if (empty($columns))
        {
            return $db->get();
        }
        else
        {
            return $db->get($columns);
        }
    }

    /**
     * 新增或者更新
     *
     * @param      $bundle
     * @param bool $ignore_update 是否忽略更新
     *
     * @return array
     */
    public function insertOrUpdate($bundle, $ignore_update = false)
    {
        // extract
        $values     = $this->value('values', $bundle, []);
        $conditions = $this->value('conditions', $bundle, []);

        // instance
        $instance = $this->first($conditions);

        // set value
        if (empty($instance))
        {
            $instance = $this->insert($values);
            return array(false, $instance);
        }
        else if (!$ignore_update)
        {
            $instance = $this->internal_save($instance, $values);
            return array(true, $instance);
        }

        return array(true, $instance);
    }

    /**
     * 纯新增
     *
     * @param $values
     *
     * @return mixed
     */
    public function insert($values)
    {
        $model_name = $this->model;
        $instance = new $model_name();

        $instance = $this->internal_save($instance, $values);
        return $instance;
    }

    /**
     * 纯更新
     *
     * @param $bundle
     *
     * @return array
     *              existed  = 是否存在
     *              instance = 搜索到的
     */
    public function update($bundle)
    {
        // extract
        $values     = $this->value('values', $bundle, []);
        $conditions = $this->value('conditions', $bundle, []);

        // instance
        $instance = $this->first($conditions);

        // set value
        if (empty($instance))
        {
            return array(false, null);
        }
        else
        {
            $instance = $this->internal_save($instance, $values);
            return array(true, $instance);
        }
    }

    /**
     * 遍历所有数据，并更新到对象上
     *
     * @param $instance
     * @param $values
     *
     * @return mixed
     */
    private function internal_save($instance, $values)
    {
        // info
        foreach ($values as $key => $value)
        {
            $instance->$key = $value;
        }

        $instance->save();
        return $instance;
    }

    public function delete($conditions)
    {
        $db = ($this->model)::query();

        foreach ($conditions as $name => $condition)
        {
            $db->where($name, $condition);
        }

        // LogHelper::info('BaseRepository delete sql', $db->toSql());

        $db->delete();
    }
}
